package ext.tianma.part.export;

import ext.com.core.CoreUtil;
import ext.com.iba.IBAUtil;
import ext.generic.erp.common.CommonPDMUtil;
import ext.tianma.part.MyPartUtil;
import ext.tianma.part.imported.ImportedExcelUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import wt.fc.ObjectReference;
import wt.fc.collections.WTCollection;
import wt.part.SubstituteQuantity;
import wt.part.WTPart;
import wt.part.WTPartHelper;
import wt.part.WTPartSubstituteLink;
import wt.part.WTPartUsageLink;
import wt.session.SessionServerHelper;
import wt.util.WTException;
import wt.vc.config.ConfigException;

public class BOMReportCommand
{
  private static final String JOURNAL_NAME = "BOMExpForm";

  //BOM结构程序导出的入口，在BOMReportAll。jsp中调用
  public static void getBOMAlls(WTPart part, HttpServletResponse response)
  {
    boolean flag = SessionServerHelper.manager.setAccessEnforced(false);
    try {
      getBOMAll(part, response);
    } catch (WTException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      SessionServerHelper.manager.setAccessEnforced(flag);
    }
  }

  public static void getBOMAll(WTPart part, HttpServletResponse response)
    throws WTException, IOException
  {
    String fileName = "BOMExpForm.xls";
    response.setContentType("application/x-msdownload");

    response.setHeader("Content-disposition", "attachment; filename=" + fileName);
    OutputStream os = response.getOutputStream();

    String filePath = "/ptc/Windchill/codebase/ext/tianma/part/export/ExportTheBOMTemplate.xls";

    HashMap<String, String> table = new HashMap<String, String>();
    table.put("源", "1");
    table.put("层", "2");
    table.put("行号", "3");
    table.put("编号", "4");
    table.put("物料描述", "5");
    table.put("版本", "6");
    table.put("单位", "7");
    table.put("数量", "8");
    table.put("状态", "9");
    table.put("环保类别", "10");
    table.put("检验标准", "11");
    table.put("产出率", "12");
    table.put("供应商", "13");
    table.put("是否替代", "14");
    table.put("BOM备注", "15");

    File file = new File(filePath);
    POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(file));
    HSSFWorkbook hwb = new HSSFWorkbook(fs);
    //得到第一个sheet页对象
    HSSFSheet sheet = hwb.getSheetAt(0);
    HSSFRow row = null;
    HSSFCell cell = null;

    BOMUtil.getTemplateLocation(sheet, table);

    String source = table.get("源").toString();
    String supplier = table.get("供应商").toString();
    String stratum = table.get("层").toString();
    String lineNumber = table.get("行号").toString();
    String number = table.get("编号").toString();
    String description = table.get("物料描述").toString();
    String versions = table.get("版本").toString();
    String unit = table.get("单位").toString();
    String quantity = table.get("数量").toString();
    String state = table.get("状态").toString();
    String envProtectionCategory = table.get("环保类别").toString();
    String inspectionStandard = table.get("检验标准").toString();
    String yield = table.get("产出率").toString();
    String isSubstitution = table.get("是否替代").toString();
    String comment = table.get("BOM备注").toString();

    List<String> nameList = new ArrayList<String>();
    nameList.add(source);
    nameList.add(stratum);
    nameList.add(lineNumber);
    nameList.add(number);
    nameList.add(description);
    nameList.add(versions);
    nameList.add(unit);
    nameList.add(quantity);
    nameList.add(state);
    nameList.add(envProtectionCategory);
    nameList.add(inspectionStandard);
    nameList.add(yield);
    nameList.add(supplier);
    nameList.add(isSubstitution);
    nameList.add(comment);

    int i = 2;

    if (part != null)
    {
      row = sheet.getRow(i);
      //获得源，并写入excel对应的单元格
      String partSource = BOMUtil.getSourceCN(part);
      cell = row.getCell(Integer.valueOf(source).intValue());
      cell.setCellValue(partSource);

      String partSupplier = (String)IBAUtil.getIBAValue(part, "partSupplier");
      cell = row.getCell(Integer.valueOf(supplier).intValue());
      cell.setCellValue(partSupplier);
      //BOM的第0层
      cell = row.getCell(Integer.valueOf(stratum).intValue());
      cell.setCellValue("0");
      //物料编号
      cell = row.getCell(Integer.valueOf(number).intValue());
      cell.setCellValue(part.getNumber());

      String partDescription = (String)IBAUtil.getIBAValue(part, "partDescription");
      cell = row.getCell(Integer.valueOf(description).intValue());
      cell.setCellValue(partDescription);

      String partVersions = BOMUtil.getVersionAndView(part);
      cell = row.getCell(Integer.valueOf(versions).intValue());
      cell.setCellValue(partVersions);

      String partState = CommonPDMUtil.getLifecycleCN(part);
      cell = row.getCell(Integer.valueOf(state).intValue());
      cell.setCellValue(partState);

      String partEnvProtectionCategory = (String)IBAUtil.getIBAValue(part, "partEnvProtectionCategory");
      cell = row.getCell(Integer.valueOf(envProtectionCategory).intValue());
      cell.setCellValue(partEnvProtectionCategory);

      String partInspectionStandard = (String)IBAUtil.getIBAValue(part, "partInspectionStandard");
      cell = row.getCell(Integer.valueOf(inspectionStandard).intValue());
      cell.setCellValue(partInspectionStandard);
      //是否替代
      cell = row.getCell(Integer.valueOf(isSubstitution).intValue());
      cell.setCellValue("0");

      writeExcelBOM(sheet, part, 1, nameList);
    }
    sheet.autoSizeColumn(1);

    hwb.write(os);
    os.close();
  }

  private static void writeExcelBOM(HSSFSheet sheet, WTPart part, int level, List<String> nameList)
    throws ConfigException, WTException, RemoteException
  {
    if ((sheet == null) || (part == null)) {
      return;
    }

    if (level > 10) {
      throw new WTException("BOM结构的层数超过10层系统无法导出！");
    }

    List<WTPartUsageLink> list = MyPartUtil.getFirstLevelUsageLink(part);

    List<WTPartUsageLink> sortList = BOMUtil.getSortList(list);

    Iterator<WTPartUsageLink> iterator = sortList.iterator();

    while (iterator.hasNext()) {
      WTPartUsageLink usageLink = (WTPartUsageLink)iterator.next();

      WTPart parentPart = usageLink.getUsedBy();

      List<String> vauleList = getUsageLinkValueList(usageLink, level);

      writeToExcel(sheet, nameList, vauleList);

      WTPart sonPart = CoreUtil.getWTPartByMasterAndView(usageLink.getUses(), usageLink.getUsedBy().getViewName());

      int countLevel = level + 1;
      writeExcelBOM(sheet, sonPart, countLevel, nameList);

      WTCollection wtcol = WTPartHelper.service.getSubstituteLinks(usageLink);

      if (wtcol != null)
        writeExcelSubPartLink(sheet, wtcol, nameList, level, parentPart.getViewName(), usageLink);
    }
  }

  private static void writeExcelSubPartLink(HSSFSheet sheet, WTCollection wtcol, List<String> nameList, int level, String view, WTPartUsageLink usageLink)
    throws WTException, RemoteException
  {
    if ((wtcol == null) || (nameList == null) || (sheet == null)) {
      return;
    }

    Iterator<?> iterator = wtcol.iterator();

    WTPartSubstituteLink wtSubstituteLink = null;

    while (iterator.hasNext()) {
      Object object = iterator.next();

      if ((object != null) && ((object instanceof ObjectReference))) {
        ObjectReference orf = (ObjectReference)object;
        Object obj = orf.getObject();

        if ((obj != null) && ((obj instanceof WTPartSubstituteLink)))
          wtSubstituteLink = (WTPartSubstituteLink)obj;
      }
      else if ((object != null) && ((object instanceof WTPartSubstituteLink))) {
        wtSubstituteLink = (WTPartSubstituteLink)object;
      }

      WTPart sonPart = CoreUtil.getWTPartByMasterAndView(wtSubstituteLink.getSubstitutes(), view);
      if ((sonPart != null) && (sonPart.getViewName().trim().equals(view)))
      {
        List<String> valueList = getPartValueList(sonPart, level, usageLink, wtSubstituteLink);

        writeToExcel(sheet, nameList, valueList);
        int countLevel = level + 1;
        writeExcelBOM(sheet, sonPart, countLevel, nameList);
      }
    }
  }

  private static void writeToExcel(HSSFSheet sheet, List<String> nameList, List<String> valueList)
  {
    if ((sheet == null) || (nameList == null) || (valueList == null)) {
      return;
    }

    HSSFRow row = null;

    for (int i = 2; i < sheet.getLastRowNum(); i++) {
      row = sheet.getRow(i);

      if (row != null) {
        HSSFCell cell = row.getCell(0);

        String value = ImportedExcelUtil.getCellValueAsString(cell, true);

        if ((value == null) || (value.trim().isEmpty()))
        {
          break;
        }
      }
    }
    HSSFCell cell = null;

    if (row != null)
      for (int i = 0; i < nameList.size(); i++) {
        cell = row.getCell(Integer.valueOf((String)nameList.get(i)).intValue());
        cell.setCellValue((String)valueList.get(i));
      }
  }

  private static List<String> getUsageLinkValueList(WTPartUsageLink usageLink, int stonumNumber)
    throws WTException, RemoteException
  {
    List<String> valueList = new ArrayList<String>();

    WTPart parentPart = usageLink.getUsedBy();

    WTPart sonPart = CoreUtil.getWTPartByMasterAndView(usageLink.getUses(), parentPart.getViewName());

    String partSource = BOMUtil.getSourceCN(sonPart);
    String partSupplier = (String)IBAUtil.getIBAValue(sonPart, "partSupplier");
    String stratum = Integer.toString(stonumNumber);
    String LineNumber = BOMUtil.getLineNumbers(usageLink, stonumNumber);
    String partNumber = BOMUtil.getPartNumber(sonPart, stonumNumber);
    String partDescription = (String)IBAUtil.getIBAValue(sonPart, "partDescription");
    String version = BOMUtil.getVersionAndView(sonPart);
    String partUnit = BOMUtil.getUnitEN(sonPart);

    String quantity = CommonPDMUtil.getQuantityValue(usageLink);
    quantity = switchQuantity(quantity);
    System.out.println("Debug   quantity : " + quantity);

    String state = CommonPDMUtil.getLifecycleCN(sonPart);
    String partEnvProtectionCategory = (String)IBAUtil.getIBAValue(sonPart, "partEnvProtectionCategory");
    String partInspectionStandard = (String)IBAUtil.getIBAValue(sonPart, "partInspectionStandard");
    String yield = (String)IBAUtil.getIBAValue(usageLink, "Yield");
    String isSubstitution = "0";
    String comment = "";

    valueList.add(partSource);
    valueList.add(stratum);
    valueList.add(LineNumber);
    valueList.add(partNumber);
    valueList.add(partDescription);
    valueList.add(version);
    valueList.add(partUnit);
    valueList.add(quantity);
    valueList.add(state);
    valueList.add(partEnvProtectionCategory);
    valueList.add(partInspectionStandard);
    valueList.add(yield);
    valueList.add(partSupplier);
    valueList.add(isSubstitution);
    valueList.add(comment);

    return valueList;
  }

  private static List<String> getPartValueList(WTPart part, int stonumNumber, WTPartUsageLink usageLink, WTPartSubstituteLink wtSubstituteLink)
    throws WTException, RemoteException
  {
    List<String> valueList = new ArrayList<String>();

    String partSource = BOMUtil.getSourceCN(part);
    String partSupplier = (String)IBAUtil.getIBAValue(part, "partSupplier");
    String stratum = Integer.toString(stonumNumber);
    String LineNumber = BOMUtil.getLineNumbers(usageLink, stonumNumber);
    String partNumber = BOMUtil.getSubPartNumber(part, stonumNumber);
    String partDescription = (String)IBAUtil.getIBAValue(part, "partDescription");
    String version = BOMUtil.getVersionAndView(part);
    String partUnit = BOMUtil.getUnitEN(part);

    SubstituteQuantity subQuantity = wtSubstituteLink.getQuantity();
    String quantity = CommonPDMUtil.getQuantityValue(subQuantity);
    quantity = switchQuantity(quantity);
    System.out.println("Debug   quantity : " + quantity);

    String state = CommonPDMUtil.getLifecycleCN(part);
    String partEnvProtectionCategory = (String)IBAUtil.getIBAValue(part, "partEnvProtectionCategory");
    String partInspectionStandard = (String)IBAUtil.getIBAValue(part, "partInspectionStandard");
    String yield = (String)IBAUtil.getIBAValue(usageLink, "Yield");
    String isSubstitution = "1";
    String comment = "";

    valueList.add(partSource);
    valueList.add(stratum);
    valueList.add(LineNumber);
    valueList.add(partNumber);
    valueList.add(partDescription);
    valueList.add(version);
    valueList.add(partUnit);
    valueList.add(quantity);
    valueList.add(state);
    valueList.add(partEnvProtectionCategory);
    valueList.add(partInspectionStandard);
    valueList.add(yield);
    valueList.add(partSupplier);
    valueList.add(isSubstitution);
    valueList.add(comment);

    return valueList;
  }

  public static String switchQuantity(String quantity)
  {
    if ((quantity == null) || (quantity.trim().isEmpty())) {
      return "";
    }

    if (quantity.contains("E")) {
      BigDecimal bd = new BigDecimal(quantity);
      quantity = bd.toPlainString();
    }

    return quantity;
  }
}